package util;

import com.ocean.nc.domain.NamedCoordinate;
import com.ocean.nc.domain.NamedTemperatureResult;
import ucar.ma2.Array;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CppgjyUtil {
    //======================================================产品评估检验西北太海温===========================================================
    // 填充值，用于判断无效数据
    private static final float FILL_VALUE = 1.0f;

    /**
     * 批量获取多个带名称的经纬度对应的海温数据
     * @param filePath NC文件路径
     * @param coordinates 带名称的经纬度列表
     * @param timeIndex 时间索引（0到168）
     * @param zIndex 深度索引（固定为0）
     * @return 带名称的海温结果列表
     */
    public static List<NamedTemperatureResult> getNamedSeaTemperatures(
            String filePath, List<NamedCoordinate> coordinates, int timeIndex, int zIndex) {

        List<NamedTemperatureResult> results = new ArrayList<>();
        NetcdfFile ncFile = null;

        try {
            // 打开NC文件（只打开一次，提高效率）
            ncFile = NetcdfFile.open(filePath);

            // 获取经纬度和温度变量
            Variable lonVar = ncFile.findVariable("lon");
            Variable latVar = ncFile.findVariable("lat");
            Variable tempVar = ncFile.findVariable("temp");

            if (lonVar == null || latVar == null || tempVar == null) {
                throw new IllegalArgumentException("NC文件中缺少必要的变量");
            }

            // 读取经纬度数据（只读取一次）
            Array lonArray = lonVar.read();
            Array latArray = latVar.read();

            // 检查时间和深度索引范围
            checkIndexRange(timeIndex, 0, 168, "时间");
            checkIndexRange(zIndex, 0, 0, "深度");

            // 遍历所有经纬度点，批量获取数据
            for (NamedCoordinate coord : coordinates) {
                // 找到最接近的经纬度索引
                int lonIndex = findClosestIndex(lonArray, coord.getLongitude());
                int latIndex = findClosestIndex(latArray, coord.getLatitude());

                // 读取对应位置的海温数据
                int[] origin = new int[]{timeIndex, zIndex, latIndex, lonIndex};
                int[] shape = new int[]{1, 1, 1, 1};
                Array tempArray = tempVar.read(origin, shape);

                // 处理温度值
                float tempValue = tempArray.getFloat(0);
                double resultValue = (Math.abs(tempValue - FILL_VALUE) < 1e-6) ? Double.NaN : tempValue;

                // 添加到结果列表
                results.add(new NamedTemperatureResult(
                        coord.getName(),
                        coord.getLongitude(),
                        coord.getLatitude(),
                        resultValue,
                        timeIndex
                ));
            }

        } catch (IOException | InvalidRangeException  e) {
            System.err.println("读取NC文件时发生错误: " + e.getMessage());
            e.printStackTrace();
        } finally {
            if (ncFile != null) {
                try {
                    ncFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return results;
    }

    /**
     * 找到最接近目标值的数组索引
     */
    private static int findClosestIndex(Array array, double target) {
        double minDiff = Double.MAX_VALUE;
        int closestIndex = 0;

        for (int i = 0; i < array.getSize(); i++) {
            double value;
            try {
                value = array.getDouble(i);
                double diff = Math.abs(value - target);
                if (diff < minDiff) {
                    minDiff = diff;
                    closestIndex = i;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return closestIndex;
    }

    /**
     * 检查索引是否在有效范围内
     */
    private static void checkIndexRange(int index, int min, int max, String name) {
        if (index < min || index > max) {
            throw new IndexOutOfBoundsException(name + "索引超出范围，必须在[" + min + ", " + max + "]之间");
        }
    }
    //======================================================产品评估检验西北太海温===========================================================
}
